/* This source file is part of the Delectable Engine.
 * For the latest info, please visit http://delectable.googlecode.com/
 *
 * Copyright (c) 2009-2010 Ryan Chew
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @file MouseManager.h
 * @brief Mouse manager component.
 */

#ifndef __DBL_MOUSEMANAGER_H_
#define __DBL_MOUSEMANAGER_H_

// Chewable Headers //
#include <cbl/Chewable.h>
#include <cbl/Core/GameComponent.h>
#include <cbl/Core/GameService.h>

// Delectable Headers //
#include "dbl/Delectable.h"
#include "dbl/Input/MouseButtons.h"
#include "dbl/Input/MouseEvents.h"
#include "dbl/Core/GameWindowEvents.h"

// External Dependencies //
#include <bitset>

namespace dbl
{
	// Using directive.
	using cbl::Event;

	//! @brief Mouse management component.
	//! Register listeners with the mouse manager events to respond to mouse input.
	//! This class depends on a GameWindow service existing in the game application.
	class DBL_API MouseManager :
		public cbl::GameComponent
	{
	/***** Properties *****/
	public:
		//! Declare mouse manager service type.
		CBL_GAMESERVICE_TYPE( MouseManager );

	/***** Events *****/
	public:
		Event< E::OnMouseMove >			OnMouseMove;	//!< Mouse move event.
		Event< E::OnMouseDrag >			OnMouseDrag;	//!< Mouse drag event.
		Event< E::OnMouseDown >			OnMouseDown;	//!< Mouse down event.
		Event< E::OnMouseUp >			OnMouseUp;		//!< Mouse up event.
		Event< E::OnMouseClick >		OnMouseClick;	//!< Mouse click event.
		Event< E::OnMouseWheel >		OnMouseWheel;	//!< Mouse wheel event.

	/***** Public Methods *****/
	public:
		//! Constructor.
		//! @param	game		Pointer to game.
		explicit MouseManager( cbl::Game & game );
		//! Destructor.
		virtual ~MouseManager();
		//! Pure virtual function to initialise component.
		virtual void Initialise( void );
		//! Pure virtual function to shut down component.
		virtual void Shutdown( void );
		//! Pure virtual update function (from IUpdatable).
		virtual void Update( const cbl::GameTime & time );

	/***** Event Handlers *****/
	public:
		//! Window mouse move event handler.
		DECL_EVENT_HANDLER( E::OnWindowMouseMove );
		//! Window mouse down event handler.
		DECL_EVENT_HANDLER( E::OnWindowMouseDown );
		//! Window mouse up event handler.
		DECL_EVENT_HANDLER( E::OnWindowMouseUp );
		//! Window mouse wheel event handler.
		DECL_EVENT_HANDLER( E::OnWindowMouseWheel );
		//! Window mouse leave event handler.
		DECL_EVENT_HANDLER( E::OnWindowMouseLeave );

	/***** Private Types *****/
	private:
		//! Button list type.
		typedef std::bitset< Mouse::Count >	ButtonList;

	/***** Private Members *****/
	private:
		ButtonList			mButtons;	//!< Button state list.
		GameWindow			* mWindow;	//!< Game window to listen to input from.
		cbl::Int32			mCurrentX;	//!< Current mouse X position.
		cbl::Int32			mCurrentY;	//!< Current mouse Y position.
	};
}

#endif // __DBL_MOUSEMANAGER_H_
